home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright Cornell University 1986. All rights are reserved.
- */
-
- #include <em.h>
-
- #include <serial.h>
- #include <3270.h>
- #include <h19.h>
- #include <errors.h>
- #include <config.h>
- #include <menudefs.h>
- #include <osutil.h>
-
- /* defines for serial port xon/xoff */
- #define SHUTOFF 1600
- #define SERBUFSIZE 4096
-
- /* modemport menu items in serial version */
-
- #define MODEMPORT 1
- #define PRINTERPORT 2
- #define NUMPORTS 2
-
- int fdcapture = -1; /* fd for transfer file */
-
- char * aserinbuf; /* input buffer to assign to Modem port */
- char * bserinbuf; /* ditto for printer port */
- char * readbuf; /* our read buffer */
- /* buffers for serial reads */
-
- char xoffmess[] = "No XON/XOFF--Capture may lose text";
-
- int noserd; /* SERD serial driver resource not present */
-
-
- struct winds * modembusy; /* port in use flag */
- struct winds * printerbusy;
-
- short modemopened; /* port was opened flag */
- short printopened;
-
- #define baud38400 1
-
- int baudrates[] = {baud57600, baud38400, baud19200, baud9600, baud4800, baud2400, baud1200, baud300};
- int dataconst[] = {data8, data7, data6};
- /* 5, 6, 7, 8 data bits */
- int parityconst[] = {noParity, evenParity, oddParity};
- /* none, even, odd */
- int stopconst[] = {stop20, stop15, stop10};
- /* 1, 1.5, 2 stop bits */
-
- extern Handle menu[];
-
- /* check the serial port for fresh data
- uses emdp by default
- */
-
- serial_service()
- {
- long readcnt;
- long sercnt;
-
- if (!emdp->connopen)
- return;
-
- SerGetBuf(emdp->refin, &sercnt);
-
- if (noserd) {
- /* if the SERD is not present we must do xon/xoff handling */
-
- if (emdp->xon) {
- if (sercnt > SHUTOFF) {
- /* turn it off */
- serputchar(X_OFF);
- emdp->xon = FALSE;
- }
- }
- else if (sercnt < SHUTOFF) {
- /* turn transmission back on */
- serputchar(X_ON);
- emdp->xon = TRUE;
- }
- }
- if (sercnt) {
- register char * readp;
- register char * bufend;
-
- if (emdp->icon_up)
- emalert(); /* highlight icon to show activity */
-
- if (sercnt > SERBUFSIZE) {
- readcnt = SERBUFSIZE;
- }
- else {
- readcnt = sercnt;
- }
- FSRead(emdp->refin, &readcnt, readbuf);
- #ifdef USESERIALWAIT
- if (autokey || readcnt <= 1)
- serialwait = 0;
- else
- serialwait = 0;
- /* wait for i ticks to service serial again */
- #endif
-
- emdp->in_cnt += readcnt;
- if ( emdp->in_cnt >= 1000 ) {
- /* turn the kilochar counter over */
- emdp->in_cnt = 0;
- emdp->kin_cnt++;
- drawincount();
- }
-
- for (readp = readbuf, bufend = readp + readcnt; readp < bufend; readp++) {
- /* mash the high bit down for the emulator */
- *readp &= 0x7f;
- }
- (*emdp->emstr)(readbuf, (unsigned short) readcnt);
- if (readcnt <= 3 || autokey || autokeypersist) {
- /* if the user is holding a key down, make sure the cursor shows */
- setcursor();
- if (autokey && autokeywait != NULL) {
- autokeypersist = TRUE;
- tm_tset(60, clrautokeywait, NULL, autokeywait);
- }
- }
-
- emdp->hycnewdata = TRUE;
-
- #ifdef SERFILECAPTURE
- /* an old feature we will probably support at a higher level */
- if (fdcapture >= 0) {
- char * stake;
-
- for (stake = readp = readbuf; readp < bufend; readp++) {
- if (*readp == LF) {
- write(fdcapture, stake, readp - stake);
- /* skip the LF */
- stake = readp + 1;
- }
- }
- if (readp > stake)
- /* write out what's left */
- write(fdcapture, stake, readp - stake);
- }
- #endif
- }
- }
-
-
- char seropenerr[] = "Not enough memory to open Serial Driver";
-
- openserport()
- {
- OSErr result;
- char leaveDTRup;
- struct winds * thedp;
-
- thedp = emdp;
- if (readbuf == NULL) {
- readbuf = malloc(SERBUFSIZE);
- if (readbuf == NULL) {
- return(-1);
- }
- }
- if (emdp->refin)
- /* don't open twice */
- return(0);
-
- if (emdp->usebport) {
- /* use the Printer Port */
- if (printerbusy) {
- if (queryserclose(printerbusy)) {
- closeconn(printerbusy);
- getcontext(thedp); /* restore our context */
- }
- else
- return(-1);
- }
- if (bserinbuf == NULL) {
- bserinbuf = malloc(SERBUFSIZE);
- if (bserinbuf == NULL) {
- error(&seropenerr[0]);
- return(-1);
- }
- }
- emdp->refin = -8;
- emdp->refout = -9;
- }
- else {
- /* use the Modem Port */
- if (modembusy) {
- if (queryserclose(modembusy)) {
- closeconn(modembusy);
- getcontext(thedp); /* restore our context */
- }
- else
- return(-1);
- }
- #ifdef OMNITEST
- if (omni_test()) {
- /* verify that the Omninet driver is not mucking around with the port */
- porterr(0);
- return(-1);
- }
- #endif
- if (aserinbuf == NULL) {
- aserinbuf = malloc(SERBUFSIZE);
- if (aserinbuf == NULL) {
- error(&seropenerr[0]);
- return(-1);
- }
- }
- emdp->refin = -6;
- emdp->refout = -7;
- }
- if ((result = RAMSDOpen(emdp->usebport ? sPortB : sPortA)) != noErr ) {
- /* open failed */
- if (result == openErr) {
- noserd = TRUE;
- error("No SERD resource available; using manual XON/XOFF");
- if ((result = OpenDriver(emdp->usebport ? "\P.BOut" : "\P.AOut", &emdp->refout) ) ) {
- porterr(result);
- return(-1);
- }
- }
- else {
- /* (result == portInUse || result == portNotCf) don't cover all bases! */
- porterr(result);
- return(-1);
- }
- }
- else {
- /* make the SERD do XON/XOFF */
- SerShk serShk;
-
- noserd = FALSE;
-
- if (emdp->baud > baud38400) {
- /* use XON/XOFF at speeds < 38,400 baud */
-
- serShk.fXOn = (Byte) TRUE; /* output XON-XOFF on/off */
- serShk.fCTS = (Byte) FALSE; /* CTS output off */
- serShk.xOn = (char) CTLQ; /* xon char DC1 */
- serShk.xOff = (char) CTLS; /* xoff char DC3 */
- serShk.errs = (Byte) 0; /* input abort settings ALL = 0160 */
- serShk.evts = (Byte) 0; /* status junk */
- serShk.fInX = (Byte) TRUE; /* input XON-XOFF on/off */
- serShk.null = (Byte) FALSE; /* CTS input off */
-
- if (Control(emdp->refout, _newrom() ? 14 : 10, &serShk))
- error(xoffmess);
- /* "Advanced" control call, dups SerHShake adding DTR input as 8th byte,
- used when not old ROM */
- }
- /* make control call so Mac + will leave its DTR line asserted when you close driver */
- if (_newrom()) {
- leaveDTRup = 0x80; /* mash bit 7 down for DTR */
- Control(emdp->refout, 16, &leaveDTRup);
- }
- }
- SerSetBuf(emdp->refin, emdp->usebport ? bserinbuf : aserinbuf, SERBUFSIZE);
-
- if (emdp->usebport) {
- printerbusy = emdp;
- printopened = TRUE;
- }
- else {
- modembusy = emdp;
- modemopened = TRUE;
- }
-
- sermenuset();
-
- if (setupport())
- return(-1);
-
- emdp->xon = TRUE;
- emdp->ucb.u_sendm = EVERYC; /* asciitoken--send promptly */
-
- tickserial = cticks + 2;
- if (tickserial == 0)
- tickserial++;
- /* start up tick counter for service */
-
- return(0);
- }
-
-
- setupport()
- {
- int serconf;
-
- if (!emdp->refin)
- return(-1);
-
- serconf = 0;
- serconf = emdp->baud
- | emdp->parity
- | emdp->stop
- | emdp->data;
-
- if (SerReset(emdp->refout, serconf) || SerReset(emdp->refin, serconf)) {
- error("Can't configure serial port");
- return(-1);
- }
- return(0);
- }
-
-
-
- localconfig()
- {
- Handle hconfig;
- struct serconfig * confp;
-
- if ((hconfig = Get1Resource('CONF', SERCONFID)) == (Handle) NULL) {
- /* no configuration resource exists */
-
- emdp->usebport = NOPORT;
-
- emdp->baud = baud9600;
- emdp->parity = noParity;
- emdp->stop = stop20;
- emdp->data = data8;
- emdp->data = data8;
-
- /* wait until user desires to open driver */
- }
- else {
- confp = (struct config *) *hconfig;
-
- emdp->usebport = confp->cport;
-
- emdp->baud = confp->cbaud;
- emdp->parity = confp->cparity;
- emdp->stop = confp->cstop;
- emdp->data = confp->cdata;
-
- ReleaseResource(hconfig);
- }
- }
-
-
- setlocalconfig()
- {
- struct serconfig * confp;
- Handle hconfig;
-
- if ((hconfig = Get1Resource('CONF', SERCONFID)) != NULL) {
- /* kill current version */
- RmveResource(hconfig);
- UpdateResFile(emdp->resfid);
- DisposHandle(hconfig);
- }
- /* add new resource */
- hconfig = NewHandle((Size) sizeof(struct serconfig));
- if (hconfig == NULL) {
- error("Out of memory");
- return(-1);
- }
-
- AddResource(hconfig, 'CONF', SERCONFID, "\P");
- if (ResError()) {
- error("Can't create CONF 1 resource");
- return(-1);
- }
-
- /* set it */
- HLock(hconfig);
-
- confp = (struct config *) *hconfig;
- confp->cport = emdp->usebport;
- confp->cbaud = emdp->baud;
- confp->cparity = emdp->parity;
- confp->cstop = emdp->stop;
- confp->cdata = emdp->data;
-
- HUnlock(hconfig);
- ChangedResource(hconfig);
- UpdateResFile(emdp->resfid);
- if (ResError()) {
- error("No serial configuration update");
- return(-1);
- }
- ReleaseResource(hconfig);
- }
-
-
- porterr(code)
- int code;
- {
- emdp->refin = emdp->refout = 0;
- if (emdp->usebport)
- error("The Printer Port can't be used--is AppleTalk off?");
- else
- error("The Modem Port can't be used");
- }
-
-
- closeserport(twp)
- struct winds * twp;
- {
- if (!twp->refin)
- return;
-
- if (twp->autohangup)
- Control(twp->refout, 18, (Ptr) NULL);
-
- if (twp->usebport) {
- if (!noserd)
- RAMSDClose(sPortB);
- else {
- CloseDriver(twp->refout);
- }
- printerbusy = NULL;
- }
- else {
- if (!noserd)
- RAMSDClose(sPortA);
- else {
- CloseDriver(twp->refout);
- }
- modembusy = NULL;
- }
- twp->refin = twp->refout = 0;
- }
-
-
- omni_test()
- {
- int refnum;
-
- if (!OpenDriver("\P.OmniDriver", &refnum)) {
- CloseDriver(refnum);
- return(TRUE);
- }
- else
- return(FALSE);
- }
-
-
- /* put out a character */
-
- serputchar(thechar)
- char thechar;
- {
- long count = 1;
-
- if (!emdp->refout)
- return(-1);
-
- serialwait = 0;
-
- FSWrite(emdp->refout, &count, &thechar);
- ++emdp->out_cnt;
- return(0);
- }
-
-
- /* update the counter, nothing else needed */
-
- serputflush()
- {
- drawoutcount();
- }
-
-
- sersendstr(strp)
- char * strp;
- {
- long count;
-
- serialwait = 0;
-
- count = strlen(strp);
- FSWrite(emdp->refout, &count, strp);
- emdp->out_cnt += count;
- drawoutcount();
- }
-
-
- /* send a block */
-
- sersendcount(strp, strcount)
- char * strp;
- short strcount;
- {
- long count = strcount;
-
- serialwait = 0;
-
- FSWrite(emdp->refout, &count, strp);
- emdp->out_cnt += count;
- drawoutcount();
- }
-
-
- sersendBreak()
- {
- long ticks;
-
- SerSetBrk(emdp->refout);
- Delay((long) 30, &ticks);
- SerClrBrk(emdp->refout);
- }
-
-
- /* routines follow to handle menus that control the serial port */
-
- menuserial(theItem)
- short theItem;
- {
- /* reset data, parity, and stop bit settings */
-
- if (theItem == SERPORTRESET) {
- SysPtr sysparam;
-
- sysparam = GetSysPPtr();
- if (emdp->usebport)
- sysparam->valid &= 0xFFFFFFF0; /* blank out Printer Port configuration */
- else
- sysparam->valid &= 0xFFFFFF0F; /* blank out Modem Port configuration */
-
- if (WriteParam()) /* save the reset configuration */
- error("Couldn't update parameter RAM");
- return(TRUE);
- }
- else if (theItem == SERPORTHANGUP) {
- serhangup(keydp);
- return(TRUE);
- }
- else if (theItem == SERAUTOHANG) {
- keydp->autohangup = !keydp->autohangup;
- keydp->confchanged = TRUE;
- CheckItem(menu[SERIALMENU], SERAUTOHANG, keydp->autohangup ? (Boolean) TRUE : (Boolean) FALSE);
- return(TRUE);
- }
-
- getcontext(keydp);
-
- switch (theItem) {
- case SERSENDHIER: {
- /* should be hierarchical, for now is sytek escape */
- (*emdp->putchar)(CTLA);
- (*emdp->putchar)(CTLB);
- return(TRUE);
- }
- case BAUD57600:
- case BAUD38400:
- case BAUD19200:
- case BAUD9600:
- case BAUD4800:
- case BAUD2400:
- case BAUD1200:
- case BAUD300:
- {
- emdp->baud = baudrates[theItem - BAUD57600];
- break;
- }
- case DATA6: {
- emdp->data = data6;
- break;
- }
- case DATA7: {
- emdp->data = data7;
- break;
- }
- case DATA8: {
- emdp->data = data8;
- break;
- }
- case PARITYNONE: {
- emdp->parity = noParity;
- break;
- }
- case PARITYEVEN: {
- emdp->parity = evenParity;
- break;
- }
- case PARITYODD: {
- emdp->parity = oddParity;
- break;
- }
- case STOP1: {
- emdp->stop = stop10;
- break;
- }
- case STOP1HALF: {
- emdp->stop = stop15;
- break;
- }
- case STOP2: {
- emdp->stop = stop20;
- break;
- }
- default: {
- return(TRUE);
- }
- }
- keydp->confchanged = TRUE;
- sermenuset();
- setupport();
- return(FALSE);
- }
-
-
- sermenuset()
- {
- int count;
-
- CheckItem(menu[SERIALMENU], SERAUTOHANG, emdp->autohangup ? (Boolean) TRUE : (Boolean) FALSE);
-
- /* blank exclusive items out */
-
- for (count = BAUD57600; count <= STOP1; count++) {
- CheckItem(menu[SERIALMENU], count, FALSE);
- }
-
- /* check baud rate */
- for (count = 0; count < NUMBAUDS; count++) {
- if (baudrates[count] == emdp->baud) {
- CheckItem(menu[SERIALMENU], count + BAUD57600, TRUE);
- }
- }
-
- /* check data bits */
- for (count = 0; count < DATAITEMS; count++) {
- if (dataconst[count] == emdp->data) {
- CheckItem(menu[SERIALMENU], count + DATA8, TRUE);
- break;
- }
- }
-
- /* check parity bits */
- for (count = 0; count < PARITYITEMS; count++) {
- if (parityconst[count] == emdp->parity) {
- CheckItem(menu[SERIALMENU], count + PARITYNONE, TRUE);
- break;
- }
- }
-
- /* check stop bits */
- for (count = 0; count < STOPITEMS; count++) {
- if (stopconst[count] == emdp->stop) {
- CheckItem(menu[SERIALMENU], count + STOP2, TRUE);
- break;
- }
- }
- }
-
-
- /* hang up the phone line(s); close will cause DTR to drop */
-
- sercleanup()
- {
- short refnum;
-
- if (noserd) {
- if (modemopened) {
- OpenDriver("\P.AOut", &refnum);
- CloseDriver(refnum);
- }
- if (printopened) {
- OpenDriver("\P.BOut", &refnum);
- CloseDriver(refnum);
- }
- }
- else {
- if (modemopened) {
- RAMSDOpen(sPortA);
- RAMSDClose(sPortA);
- }
- if (printopened) {
- RAMSDOpen(sPortA);
- RAMSDClose(sPortB);
- }
- }
- }
-
-
- /* hangup the phone line by dropping DTR */
-
- serhangup(twp)
- struct winds * twp;
- {
- if (twp->refout) {
- Control(twp->refout, 18, (Ptr) NULL);
- }
- else {
- /* driver is closed, reopen & THEN hang it up */
- getcontext(twp);
- openserport();
- Control(twp->refout, 18, (Ptr) NULL);
- closeserport(twp);
- }
- }
-
-